iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

如果各位有在使用Vue,看到這二個HTML Element會有種很熟悉的感覺。你沒看錯,Vue和web component在這裡也有許多共同之處。

HTML import

提到template and slot就不得不先說明HTML import,這個功能本來也是web component的技術之一。可以先把HTML,css和js寫入一個HTML,再分別載入到主HTML。但因為各種原因,最後本功能取消,現在只能在Vue的單文件模式中看到HTML import的殘影了。

如果有在使用Vue的單文件模式,在一個檔案中用'template'、'style'和'script'三個標籤把HTML,css,js分別包起來就是HTML import的目標

template

因為HTML import技術消失,template 這個HTML element現在的作用就像是React的React.Fragment,可以一次設定多個節點又不用附加多餘的節點。

HTML

<ul id='ul'></ul>
<template id='li-list'>
    <li>111</li>
    <li>222</li>
    <li>333</li>
<template>
<-- 上下二個會出現一樣的結果 -->
<ul>
    <li>111</li>
    <li>222</li>
    <li>333</li>
</ul>

Javascript

const templateNode = document.getElementById('li-list')
const liList = templateNode.content.cloneNode(true);
const ulNode = document.getElementById('ul')
ulNode.appendChild(liList)

React 對應的寫法

const Ul = () => (
    <ul>
        <LiList />
    </ul>
)
const LiList = () => (
    <>
        <li>111</li>
        <li>222</li>
        <li>333</li>
    </>
)

slot

slot 這個HTML element需要使用shadow DOM才能發揮功能,之後的文章會進一步說明。

如果有在使用Vue的話,web component和Vue的slot除了語法不一樣之外,使用起來一模一樣。

HTML的部分

<my-com>
    <div slot="slot1">111</div>
    <div slot="slot2">222</div>
    <div>333</div>
</my-com>
<--  上面web component的Shadow DOM會形成下面的樣子  -->
<div>
    <div>
        <div>111</div>
    </div>
    <div>
         <div>333</div>
    </div>
    <div>
        <div>222</div>
    </div>
</div>

Javascript的部分

class MyComponent extends HTMLElement {
    constructor() {
        super();
        this.render = this.render.bind(this);
    }
    connectedCallback() {
        // 下面二行的用法之後的文章會解釋
        this.attachShadow({mode: 'open'});
        this.shadowRoot.appendChild(this.render())
    }
    render() {
        const template = document.createElement('template');
        template.innerHTML = `
            <div>
                <div>
                    <slot name="slot1"></slot>  // 把子節點中,屬性slot是'slot1'的子節點放入這裡
                </div>
                <div>
                    <slot></slot>  // 把子節點中,沒有設定屬性slot的子節點放入這裡
                </div>
                <div>
                    <slot name="slot2"></slot>  // 把子節點中,屬性slot是'slot2'的子節點放入這裡
                </div>
            </div>
        `;
        return template.content;
    }
}
customElements.define('my-com', MyComponent);

上一篇
[Day5] Custom element - life cycle(生命周期)
下一篇
[Day7] shadow DOM 的使用和問題
系列文
web component - 次世代網頁技術的重要拼圖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言